home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Ham Radio 2000
/
Ham Radio 2000.iso
/
ham2000
/
morse
/
staton
/
cpo_spk.txt
< prev
next >
Wrap
Text File
|
1994-04-22
|
10KB
|
524 lines
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!;
; COPYRIGHT (C) 1994 KEN STATON ;
; ALL RIGHTS RESERVED ;
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!;
#INCLUDE "GLOBALS.TXT"
.MSFIRST ; MOST SIGNIFICANT BYTE FIRST!
;
; Ken Staton
; Feb 9, 1993 First coding
; Apr 3, 1993 Added DAC support
; ~44K of digitized speech:
; A-Z = 26 + 0-9 = 10 + {.,?} = 3 total = 39
; {sk,bt,ar,dn,kn} = 5; 39 + 5 = 44
; could implement {sk,bt,ar,dn,kn} as
; concatenations of letters
; Jun 3, 1993 Added ADPCM digitized speech
; Aug 17, 1993 Cleanup. Removed Debug & RS232.
; Aug 25, 1993 Changed 4Mc->3.2768Mc
; Fixed interrupt problem (not re-entrant)
; by disabling INTS in speak & morse
; Jan 25, 1994 Added BUILDIT speech mode in preparation
; for allophone based speech. Currently
; used for concatenating sounds of prosigns.
; Feb 1, 1994 Changed 3.2768Mc->6.0Mc to support 8KHz data rate.
; Mar 19, 1994 Added SET Option. Commented out to disable.
; Apr 16, 1994 Fixed char rate bug when changed from default.
; Apr 20, 1994 Added programmed delay before and after speaking
; Apr 22, 1994 Version 1.0
;
;---------------------------------------------------------------------
;
; Select options using ext_int0
; Options are:
; Speed
; 5@16
; 13@18
; 20@23
; Toggle
; SPEECH
; Random Chars
; Random Groups of five chars
; Sequence Chars
; Toggle Set (see SUBSET; not enabled)
; LETTERS
; NUMBERS
; PROSIGNS
; PUNCTUATION
;** PROGRESSIONS
;** COMPLEMENTS
; ** = not yet implemented...
;
;
#INCLUDE "ISR_INIT.TXT"
;**************************************************************
;
; MAIN LOOP
;
MAIN
CJNE R4,#RAN,MODE0 ;if R4=Random then JMP RCHARS
LJMP RCHARS
MODE0 CJNE R4,#SEQ,MODE1 ;if R4=Sequence then JMP CYCLE
LJMP CYCLE
MODE1 CJNE R4,#GRP,MODE2 ;if R4=Group then JMP RGRP
LJMP RGRP
MODE2 SJMP MAIN
;**************************************************************
;
; RCHARS - Random Characters
;
RCHARS
LCALL RANDOM ; GENERATE RANDOM INDEX
TRUNC MOV A,PH
RR A
RR A
RR A
MOV COUNT,A ; SAVE INDEX
CLR C
SUBB A,#SETSIZE ; A <- A - C - #data
JNC RCHARS ; C=0 -> A>=SETSIZE
; for INDEX: 0..SETSIZE-1
MOV A,COUNT
LCALL SUBSET
JZ RCHARS
JNB CODE,RCPO1
MOV A,COUNT ; restore index
LCALL MORSE ; sound code
RCPO1
JNB SPEAK,RCPO2
MOV A,COUNT ; restore index
LCALL SPEECH ; speak code
RCPO2
LJMP MAIN ; RESTART MAIN LOOP
;**************************************************************
;
; RGRP - Random Groups
;
RGRP
PUSH RH
PUSH RL
LCALL RCODE
LCALL RCODE
LCALL RCODE
LCALL RCODE
LCALL RCODE
LCALL WORD_DLY
POP RL ; Restore seed. psuedorandom,
POP RH ; so sequence will be the same...
LCALL RTALK
LCALL RTALK
LCALL RTALK
LCALL RTALK
LCALL RTALK
LJMP MAIN ; RESTART MAIN LOOP
;**************************************************************
;
; RCODE - Random Code SUBROUTINE for RGRP
;
RCODE LCALL RANDOM ; GENERATE RANDOM INDEX
MOV A,PH
RR A
RR A
RR A
MOV COUNT,A ; SAVE INDEX
CLR C
SUBB A,#SETSIZE
JNC RCODE ;C=0 -> A>=SETSIZE
; for INDEX: 0..43
; for INDEX: 0..SETSIZE-1
MOV A,COUNT
LCALL SUBSET
JZ RCODE
MOV A,COUNT ; RESTORE INDEX
LCALL MORSE ; sound code
RET ; DONE
;**************************************************************
;
; RTALK - Random Talk SUBROUTINE for RGRP
;
RTALK LCALL RANDOM ; GENERATE RANDOM INDEX
MOV A,PH
RR A
RR A
RR A
MOV COUNT,A ; SAVE INDEX
CLR C
SUBB A,#SETSIZE
JNC RTALK ; C=0 -> A>=SETSIZE
; for INDEX: 0..SETSIZE-1
MOV A,COUNT
LCALL SUBSET
JZ RTALK
MOV A,COUNT ; RESTORE INDEX
JNB SPEAK,RTDONE
LCALL SPEECH ; speak code
RTDONE
RET ; DONE
;**************************************************************
;
; CYCLE - Cycle sequentially through character set
;
CYCLE
MOV COUNT,#0
NEXT_C MOV A,COUNT
LCALL SUBSET
JZ NEXT_C
MOV A,COUNT
JNB CODE,CYC1
LCALL MORSE ; sound code
CYC1
JNB SPEAK,CYC2 ; test if speak on
MOV A,COUNT ; restore index
LCALL SPEECH ; speak code
CYC2
INC COUNT
MOV A,COUNT
CJNE A,#SETSIZE,NEXT_C
LJMP MAIN ; RESTART MAIN LOOP
;
;*************************************************************************
;
; RANDOM
;
; RANDOM NUMBERS BETWEEN 0 AND {26+10+3+4 = 43}-1 = 42
; i.e. mod 42
;
; Best bet is to generate seed by having 16 bit counter that
; increments until input at power up...this requires setting
; mode, or maybe just indicating when to start...
;
; Some external asyncronous event must establish seed.
; See EXT0 in INIT_ISR.
;
; Algorithm described in:
; The Art of Computer Programming Volume 2, Seminumerical Algorithms
; Donald Knuth
;
; X <- (aX + c) mod m
;
; m = 65536
; c/m ~ 0.2113248654
; c odd
; 13.85 -> c = 13
; a > sqrt(m), a > m/100, a < m - sqrt(m)
; 256 < 655 < a < 65280
; a = 31415 {= 122*256 + 183}
;
; X <- (31415 * X + 13) mod 65536
;
; NOTE: that the arithmetic done in a 16 bit word
; is mod 2^16 = 65536
;
; A * B = (AL + 2^8 * AH) * (BL + 2^8 * BH)
; = AL * BL + 2^8(AL * BH + AH * BL) + 2^16(AH * BH)
; A * 31415 = AL * 183 + 2^8(AL * 122 + AH * 183) + 2^16(AH * 122)
;
RANDOM
MOV A,RL
MOV B,#183
MUL AB ; A[7..0],B[15..8] product bits
MOV PL,A
MOV PH,B
MOV A,RL
MOV B,#122
MUL AB
ADD A,PH
MOV PH,A
MOV A,RH
MOV B,#183
MUL AB
ADD A,PH
MOV PH,A
CLR C ; NOW ADD c
MOV A,PL
ADDC A,#13
MOV PL,A
JNC NOCARRY
INC PH
NOCARRY
MOV RL,PL
MOV RH,PH
RET ; DONE RANDOM
;
;*************************************************************************
;
; Define code for MORSE SUBROUTINE
;
;
; numbers 5 bits
; punctuation 6 bits
; letters <= 4 bits
;
; b7 b6 b5 | b[4:0] -> group
;---------------|--------------------------
; 0 0 d | number or prosign
; 0 1 d | punctuation or prosign
; 1 0 0 | 1 element letter
; 1 0 1 | 2 element letter
; 1 1 0 | 3 element letter
; 1 1 1 | 4 element letter
; |
; d => don't | 1 => dah
; care | 0 => dit
;
CODE_TBL
LETTERS
MCA .DB 10100001B
MCB .DB 11101000B
MCC .DB 11101010B
MCD .DB 11000100B
MCE .DB 10000000B
MCF .DB 11100010B
MCG .DB 11000110B
MCH .DB 11100000B
MCI .DB 10100000B
MCJ .DB 11100111B
MCK .DB 11000101B
MCL .DB 11100100B
MCM .DB 10100011B
MCN .DB 10100010B
MCO .DB 11000111B
MCP .DB 11100110B
MCQ .DB 11101101B
MCR .DB 11000010B
MCS .DB 11000000B
MCT .DB 10000001B
MCU .DB 11000001B
MCV .DB 11100001B
MCW .DB 11000011B
MCX .DB 11101001B
MCY .DB 11101011B
MCZ .DB 11101100B
NUMBERS
MC1 .DB 00001111B
MC2 .DB 00000111B
MC3 .DB 00000011B
MC4 .DB 00000001B
MC5 .DB 00000000B
MC6 .DB 00010000B
MC7 .DB 00011000B
MC8 .DB 00011100B
MC9 .DB 00011110B
MC0 .DB 00011111B
PUNCTUATION
MCPP .DB 01010101B
MCPC .DB 01110011B
MCPQ .DB 01001100B
PROSIGNS
MCSDN .DB 00010010B
MCSSK .DB 01000101B
MCSBT .DB 00010001B
MCSAR .DB 00001010B
MCSKN .DB 00010110B ; <<< NOT PART OF TEST SET!
SUBSET
;
; CHECKS IF CHARACTER INDEX IS IN AN ENABLED SUBSET
; RETURNS ACC=0 IF NOT ENABLED
; RETURNS ACC=1 IF ENABLED
;
; CLR C
; SUBB A,#CONST ; C=0 -> A>=CONST
;
; CLR C
; SUBB A,#26 ; A={0..25} -> LETTER
; JC IN_GL ; C=1 -> A<26
; MOV A,COUNT
; SUBB A,#36 ; A={26..35} -> NUMBER
; JC IN_GN ; C=1 -> 26<=A<36
; MOV A,COUNT
; SUBB A,#39 ; A={36..38} -> PUNCTUATION
; JC IN_GP ; C=1 -> 36<=A<39
; MOV A,COUNT
; SUBB A,#43 ; A={39..42} -> PRO-SIGN
; JC IN_GS ; C=1 -> 39<=A<43
;IN_GL
; JNB GL,NOT_IN_SET
; MOV A,#YES
; RET
;IN_GN
; JNB GN,NOT_IN_SET
; MOV A,#YES
; RET
;IN_GP
; JNB GP,NOT_IN_SET
; MOV A,#YES
; RET
;IN_GS
; JNB GS,NOT_IN_SET
; MOV A,#YES
; RET
;NOT_IN_SET
; MOV A,#NO
; RET
MOV A,#YES ; always enabled for now...
RET
SPEECH
;
; INPUT ACC = index for sound table, which must match
; order of code table
CLR C
RLC A ;MUL BY 2 for 2 byte address entries in table
MOV TMP2,A ;save index by 2
MOV DPTR,#SOUND_TBL
MOVC A,@A+DPTR
MOV ADDR_H,A ;save addrh
MOV A,TMP2 ;restore index by 2
INC A ;get rest of addr
MOVC A,@A+DPTR
MOV DPL,A
MOV DPH,ADDR_H
;
; delay after code - before speaking
;
MOV R7,DLY_B4
LCALL DELAY
MOV R7,DLY_B4
LCALL DELAY
MOV R7,DLY_B4
LCALL DELAY
MOV R7,DLY_B4
LCALL DELAY
MOV TMP2,#0 ;start at entry 0
BLD_LOOP
MOV A,TMP2
MOVC A,@A+DPTR
CJNE A,#PA1,TP2 ;test if 1mS pause
SJMP PAUSE1
TP2 CJNE A,#PA10,TP3 ;test if 10mS pause
SJMP PAUSE2
TP3 CJNE A,#PA100,TP4 ;test if 100mS pause
SJMP PAUSE3
TP4 CJNE A,#PA300,TP5 ;test if 500mS pause
SJMP PAUSE4
TP5 CJNE A,#PA500,TTERM ;test if terminator (0FFH)
SJMP PAUSE5
TTERM CJNE A,#0FFH,BLD_MORE
;
; delay after speaking - before next code
;
MOV R7,DLY_AR
LCALL DELAY
MOV R7,DLY_AR
LCALL DELAY
MOV R7,DLY_AR
LCALL DELAY
MOV R7,DLY_AR
LCALL DELAY
RET ; DONE
BLD_MORE
LCALL MAKESOUND
BMORE INC TMP2
SJMP BLD_LOOP
;
; These pauses are used in speech concatenation
;
PAUSE1
MOV R7,#1
LCALL DELAY
SJMP BMORE
PAUSE2
MOV R7,#10
LCALL DELAY
SJMP BMORE
PAUSE3
MOV R7,#100
LCALL DELAY
SJMP BMORE
PAUSE4
MOV R7,#150
LCALL DELAY
MOV R7,#150
LCALL DELAY
SJMP BMORE
PAUSE5
MOV R7,#250
LCALL DELAY
MOV R7,#250
LCALL DELAY
SJMP BMORE
SOUND_TBL
#INCLUDE "TABLE02.TXT" ; Defines contatenations
MAKESOUND
#INCLUDE "SPEAK.TXT"
MORSE
#INCLUDE "MORSE.TXT"
.ORG (0FFFFH-51)
.TEXT "COPYRIGHT (C) 1994 KEN STATON. ALL RIGHTS RESERVED"
.ORG 0FFFFH
.DB 0FFH
.END